package com.karina.visualization.chart.skins;

import com.karina.visualization.chart.client.Gradient;
import com.karina.visualization.chart.client.Graphics;
import com.karina.visualization.chart.model.SeriesModel;
import com.karina.visualization.chart.model.SeriesModel.CategoryValue;

public class PieSkin extends BaseSkin<SeriesModel<CategoryValue>> {

	@Override
	public void draw(Graphics grahpics) {
		int radius = (Integer) getStyleDeclaretion().getStyle("radius");
		if (radius <= 0) {
			radius = 100;
		}
		double rotation = ((Double) getData().getValue().getValue()) * Math.PI
				* 2;
		double startAngle = getData().getRelativeX() * Math.PI * 2;
		drawPie(grahpics, getData().getIndex(), radius, startAngle, rotation,
				getData().getName());
	}

	@Override
	public void cleanup(Graphics graphics) {

	}

	@Override
	public void refresh(Graphics graphics) {

	}

	private int getCenterX() {

		return getData().getWidth() / 2;

	}

	private int getCenterY() {
		return getData().getHeight() / 2;
	}

	private void drawIndicator(Graphics g, String desp, double radius,
			double angle, double rotation, int x, int y) {

		int cx = getCenterX();
		int cy = getCenterY();

		int dsx = x - cx;
		int dsy = y - cy;
		int distance = 30;

		int xo = (int) (cx + radius * Math.cos(angle + rotation / 2));
		int yo = (int) (cy + radius * Math.sin(angle + rotation / 2));
		String msg = "" + (int) (rotation / (Math.PI * 2) * 100) % 100 + "% :"
				+ desp;

		if (dsx > 0 && dsy > 0) {
			drawIndicator(g, msg, xo, yo, (x + distance), (y + distance));
		} else if (dsx < 0 && dsy > 0) {
			drawIndicator(g, msg, xo, yo, (x - distance), (y + distance));
		} else if (dsx > 0 && dsy < 0) {
			drawIndicator(g, msg, xo, yo, (x + distance), (y - distance));
		} else {
			drawIndicator(g, msg, xo, yo, (x - distance), (y - distance));
		}

	}

	private void drawIndicator(Graphics g, String msg, int x0, int y0, int x1,
			int y1) {
		g.saveContext();
		g.beginPath();
		g.moveTo(x0, y0);
		g.lineTo(x1, y1);

		if (x1 >= x0) {
			g.lineTo(x1 + 50, y1);
			g.drawText(x1, y1, msg, "left", "bottom");
		} else {
			g.lineTo(x1 - 50, y1);
			g.drawText(x1, y1, msg, "right", "bottom");
		}
		g.stroke();
		g.endPath();
		g.restoreContext();
	}

	private void drawPie(Graphics g, int index, double radius, double angle,
			double rotation, String msg) {
		int xo = getCenterX();
		int yo = getCenterY();
		int x1 = xo + (int) (radius * Math.cos(angle));
		int y1 = yo + (int) (radius * Math.sin(angle));
		int x2 = xo + (int) (radius * Math.cos(angle + rotation));
		int y2 = yo + (int) (radius * Math.sin(angle + rotation));

		int x3 = xo + (int) (radius * Math.cos(angle + rotation / 2));
		int y3 = yo + (int) (radius * Math.sin(angle + rotation / 2));
		Gradient gradient = Graphics.PRE_DEFINED_GRADIENT_ARRAY[index];

		g.saveContext();
		g.beginPath();
		g.fillStyle(xo - radius / 2, yo - radius / 2, xo + radius / 2, yo
				+ radius / 2, gradient);
		g.arc(xo, yo, radius, angle, angle + rotation, false);
		g.fill();
		g.endPath();
		g.restoreContext();

		g.saveContext();

		g.beginPath();

		g.moveTo(xo, yo);
		g.lineTo(x1, y1);

		g.moveTo(xo, yo);
		g.lineTo(x2, y2);
		g.setLineWidth(2);
		g.setLineColor(255, 255, 255, 1.0);
		g.stroke();

		g.endPath();
		g.restoreContext();

		g.saveContext();
		g.beginPath();
		g.setLineColor(255, 255, 255, 1.0);
		g.setLineWidth(2);
		g.arc(xo, yo, radius - 5, angle, angle + rotation, false);
		g.stroke();
		g.endPath();
		g.restoreContext();
		drawIndicator(g, msg, radius, angle, rotation, x3, y3);
	}
}
